package com.ossean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import com.ossean.databaseSource.DBSource;
import com.ossean.databaseSource.GatherDao;
import com.ossean.model.EddRelations;
import com.ossean.model.GatherProjectsModel;
import com.ossean.util.MergeProjectsUtil;

@Component
public class MergeProjectsByHomepageOnly {
	Logger logger = Logger.getLogger(this.getClass());

	@Resource
	private DBSource dbSource;
	@Resource
	private GatherDao gatherDao;
	
	@Qualifier("mergeProjectsUtil")
	@Autowired
	private MergeProjectsUtil mergeProjectsUtil;
	
	private static String pointerTableName = "edd_pointers";
	private static String sourceTableName = "gather_projects";
	private static String eddRelationTableName = "edd_relations_test";
	private static String targetTableName = "edd_relations_homepage_only1";
	
	public int readPointer(String table, String source, String target){
		int pointer = 1;
		try {
			pointer = dbSource.getPointer(table, source, target);
		} catch(Exception e) {
			logger.info("No such pointer! Create one");
			dbSource.insertPointer(table, source, target, pointer);
		}
		return pointer;
	}
	
	public void start(){
		while(true){
			int maxId = dbSource.getMaxId(sourceTableName);
			int startId1 = readPointer(pointerTableName, sourceTableName, targetTableName);
			if(startId1 > maxId){
				logger.info("finish program! HAHAHA");
				System.exit(0);
			}
			//获取当前的项目
			GatherProjectsModel project = gatherDao.selectGPMById(sourceTableName, startId1);
			if(project == null){
				//表示项目不存在
				logger.info("项目：" + startId1 + " 不存在");
				dbSource.updatePointer(pointerTableName, sourceTableName, targetTableName, startId1 + 1);
				continue;
			}
			String homepage = project.getHomepage();
			String source   = project.getSource();
			//如果是null 不需要查找相同homepage的项目
			List<GatherProjectsModel> sameHomepageList = new ArrayList<GatherProjectsModel>();
			if(source=="apache" && (homepage == null||homepage.equals("")) ){
				homepage = project.getUrl();
				dbSource.updateApacheHomepageById(sourceTableName, homepage, project.getId());
			}
			if(homepage != null && !"".equals(homepage)){
				homepage = homepage.trim();
				//查找所有相同homepage字段的项目
				//判断homepage是否有http://或https://
				int index_http = homepage.indexOf("http://");
				int index_https = homepage.indexOf("https://");
				if(index_http == 0){
					homepage = homepage.substring(index_http + 7);	//去除http://
				}else if(index_https == 0){
					homepage = homepage.substring(index_https + 8);	//去除https://
				}else{
					//表示不是以http或https开头
				}
				
				if((homepage.lastIndexOf("/") == homepage.length()-1) && (homepage.length() != 0)){
					//如果homepage的最后一个字符是/ 需要去除掉
					homepage = homepage.substring(0, homepage.length() - 1);
				}
				if(homepage.length() > 0){
					//为homepage添加http或https头
					String homepage1 = "http://" + homepage;
					String homepage2 = "https://" + homepage;
					String homepage3 = "http://" + homepage + "/";
					String homepage4 = "https://" + homepage + "/";
					
					sameHomepageList = gatherDao.selectGPMBySameHomePage(sourceTableName,homepage, homepage1, homepage2, homepage3, homepage4, project.getId(), project.getSource());//认为一定是相同的项目
				}
			}
			
			//处理sameHomepageList 如果edd_relations表中有包含对应id的记录 则将所有的id糅合在一起，删除以前的记录，添加新的edd_relation记录
			if(sameHomepageList.size() == 0){
				//表示没有找到对应homepage的项目
				//更新指针
				if(homepage == null){
					logger.info(project.getId() + "项目：" + project.getName() + " homepage为null");
				}else{
					logger.info(project.getId() + "项目：" + project.getName() + " 没有找到相同homepage的项目");
				}
				List<EddRelations> relationsList_now = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, project.getId());
				if(relationsList_now.size()==0){
					EddRelations relation = new EddRelations();
					String gather_projects_id = ","+project.getId()+",";
					relation.setGather_projects_ids(gather_projects_id);
					dbSource.insertEddRelations(eddRelationTableName, relation);
				}
				dbSource.updatePointer(pointerTableName, sourceTableName, targetTableName, startId1 + 1);
				continue;
			}
			//加入了项目本身
			sameHomepageList.add(project);
			
			List<EddRelations> relationsList = new ArrayList<EddRelations>();
			EddRelations relation_model = new EddRelations();
			relation_model.setGather_projects_ids(","+project.getId()+",");
			relationsList.add(relation_model); //relationsList用于记录包含当前项目在内的
			
			List<EddRelations> relationsList_matched = new ArrayList<EddRelations>();//匹配上的项目在edd_relations表中的记录
			for(int i = 0; i < sameHomepageList.size(); i++){
				GatherProjectsModel model_sameHP = sameHomepageList.get(i);
				//查找edd_relations表得到相应的记录
				List<EddRelations> eddRelationList = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, model_sameHP.getId());
				for(EddRelations relation:eddRelationList){
					relationsList.add(relation);
					relationsList_matched.add(relation);
				}
				if(eddRelationList.size() == 0){
					//表示之前没有匹配上项目的匹配记录 需要插入这条记录 eg: ,12,
					EddRelations relation = new EddRelations();
					relation.setGather_projects_ids(","+model_sameHP.getId()+",");
					relationsList.add(relation); //relationsList用于记录包含当前项目在内的
				}
			}
			
			
			//根据新的匹配结果形成一个新的EddRelation对象
//			EddRelations new_relation = new EddRelations();
//			String new_gather_projects_ids = ",";
//			for(GatherProjectsModel model:sameHomepageList){
//				new_gather_projects_ids = new_gather_projects_ids + model.getId() + ",";
//			}
//			new_relation.setGather_projects_ids(new_gather_projects_ids);
//			relationsList.add(new_relation);
//			//倘若都是新项目，则resultInEddRelation为空！longestRelation为空
//			List<EddRelations> resultInEddRelation = new ArrayList<EddRelations>();
//			for(GatherProjectsModel model:sameHomepageList){
//				List<EddRelations> relationList = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, model.getId());
//				for(EddRelations relation:relationList){
//					resultInEddRelation.add(relation);
//				}
//			}
//			
//			//判断resultInEddRelation中最长的gather_projects_ids是不是包含了其他所有的结果项目 如果不是则需要将所有的项目id统计到一起并删除原来的所有结果
//			//找到resultInEddRelation中最长的gather_projects_ids对应的对象
//			EddRelations longestRelation = findLongestGatherProjectsIds(resultInEddRelation);
//			
//			//将new_relation插入resultInEddRelation中
//			resultInEddRelation.add(new_relation);
//			
//			//relationsList_now表示目前正在处理的项目在edd_relations表中的记录 需要在插入新的edd_relations对象前查找
//			List<EddRelations> relationsList_now = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, project.getId());
//			
//			//判断最长的gather_projects_ids中是不是包括了所有其他eddrelation中匹配到的id
//			//倘若都是新项目，则longestRelation为空！
//			boolean hasOthers = containOtherRelations(longestRelation, resultInEddRelation);
//			
//			//如果hasOthers为true 表示确实包含所有其他的relation（包括新加入的relation） 因此不用重新组合插入新的relation
//			if(hasOthers == true){
//				//删除除longestRelation以外所有数据库中的relation 其中new_relation对应的id为默认值0 可以一并删除（数据库中没有 但删除操作可以继续）
//				for(EddRelations relation:resultInEddRelation){
//					if(relation.getId() != longestRelation.getId()){
//						dbSource.deleteEddRelationsItem(eddRelationTableName, relation.getId());
//					}
//				}
//			}
			
			//如果hasOthers为false 表示存在edd_relations对象中的项目id不包含在最长的gather_projects_ids中 需要重新组合所有id 并删除原来的edd_relations插入新的edd_relations
			List<EddRelations> relationsList_now = dbSource.getEddRelationsByGatherProjectsId(eddRelationTableName, project.getId());
			String new_relation_string = mergeProjectsUtil.hasDiffProjFromSameCommunity(relationsList);
			//判断所有id是不是都来自于不同的社区 如果是则插入newEddRelation 如果不是 则不进行操作
			if(new_relation_string == null){
					//表示有来自同一社区的项目，则不进行后续操作
					if(relationsList_now.size() == 0){
						//表示不是更新的项目 需要插入当前项目本身的记录
						EddRelations relation = new EddRelations();
						String gather_projects_id = ","+project.getId()+",";
						relation.setGather_projects_ids(gather_projects_id);
						dbSource.insertEddRelations(eddRelationTableName, relation);
					}
			}
			else{
				//表示匹配结果中不存在同一个社区不同的多个项目匹配到一起
				EddRelations eddRelation = new EddRelations();
				eddRelation.setGather_projects_ids(new_relation_string);
				dbSource.insertEddRelations(eddRelationTableName, eddRelation);//插入最新的结果集
				/**
				 * 删除关联项目在edd_relations表中对应的记录
				 */
				if(relationsList_matched.size() !=0){
					for(EddRelations relation:relationsList_matched)
						deleteExistEddRelations(relation);
				}/**
				 * 如果是更新项目 需要查看edd_relations表中是否有该记录 如果有要删除掉
				 */
				if(relationsList_now.size() !=0){
				for(EddRelations relation:relationsList_now)
					deleteExistEddRelations(relation);
				}
			}
			dbSource.updatePointer(pointerTableName, sourceTableName, targetTableName, startId1 + 1);
			
		}
			
			
		}
		
		
	public void deleteExistEddRelations(EddRelations relation){
		//删除之前对应的relation记录
		int edd_relation_id = relation.getId();
		dbSource.deleteEddRelationsItem(eddRelationTableName, edd_relation_id);
	}
	
	
	private EddRelations findLongestGatherProjectsIds(List<EddRelations> eddRelationList){
		EddRelations result = new EddRelations();
		int maxLength = 0;
		for(EddRelations relation:eddRelationList){
			String gather_projects_ids = relation.getGather_projects_ids();
			int length = gather_projects_ids.split(",").length-1;
			if(length > maxLength){
				maxLength = length;
				result = relation;
			}
		}
		return result;
	}
	
	
	private boolean containOtherRelations(EddRelations longestRelation, List<EddRelations> relationList){
		boolean result = true;
//System.out.println(longestRelation);
		if(longestRelation.getGather_projects_ids() == null)
			return false;
		for(EddRelations relation:relationList){
			if(containRelation(longestRelation, relation) == false){
				return false;
			}
		}
		return result;
	}
	
	private boolean containRelation(EddRelations longestRelation, EddRelations relation){
		boolean result = false;
		String longestIds = longestRelation.getGather_projects_ids();
		String[] longestIdArray = longestIds.split(",");
		//去除第一个空串元素
		longestIdArray = removeFirstElement(longestIdArray);
		String[] relationIdArray = relation.getGather_projects_ids().split(",");
		//去除第一个空串元素
		relationIdArray = removeFirstElement(relationIdArray);
		//查看array2中的元素在array1中是否都存在
		result = containArray(longestIdArray, relationIdArray);
		return result;
	}
	
	private boolean containArray(String[] array1, String[] array2){
		boolean result = true;
		for(String s2:array2){
			int i;
			for(i = 0; i < array1.length; i++){
				String s1 = array1[i];
				if(s1.equals(s2)){
					break;	//表示存在结果 匹配下一个string
				}
			}
			if(i == array1.length){
				//表示匹配到最后都没有匹配到合适的结果
				return false;
			}
		}
		return result;
	}
	
	
	//重新组合List<EddRelations>中EddRelation对象对应的gather_projects_ids对应的id数据
	private EddRelations combineNewEddRelation(List<EddRelations> eddRelationList){
		EddRelations result = new EddRelations();
		String new_gather_projects_ids = ",";
		Map<String, Integer> idMap = new HashMap<String, Integer>();
		for(EddRelations relation:eddRelationList){
			String gather_projects_ids = relation.getGather_projects_ids();
			String[] idArray = gather_projects_ids.split(",");
			for(String id:idArray){
				if(!"".equals(id))
					idMap.put(id, 1);
			}
		}
		//根据map中的key形成new_gather_projects_ids
		Set<String> keys = idMap.keySet();
		Iterator it = keys.iterator();
		while(it.hasNext()){
			String key = it.next().toString();
			new_gather_projects_ids = new_gather_projects_ids + key + ",";
		}
		result.setGather_projects_ids(new_gather_projects_ids);
		return result;
	}
	
	
	private String[] removeFirstElement(String[] array){
		String[] result = new String[array.length-1];
		for(int i = 1; i < array.length; i++){
			result[i-1] = array[i];
		}
		return result;
	}
	
	public static void main(String[] args){ 
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/applicationContext*.xml");
		MergeProjectsByHomepageOnly Main = applicationContext.getBean(MergeProjectsByHomepageOnly.class);
		Main.start();
	}
	
}
